#include "../include/head.h"
const char* userDir = "../../server/userDir";
const char* dataServerArr[3]=
{
    "127.0.0.1 33333",
    "127.0.0.1 44444",
    "127.0.0.1 55555"
};

int sendError(int netfd,const char* errmsg)
{
    int type = DIR_ERR;
    char* msg = {0};
    int msglen = strlen(errmsg);
    memcpy(msg,errmsg,msglen);
    send(netfd,&msglen,sizeof(int),MSG_NOSIGNAL);
    send(netfd,msg,msglen,MSG_NOSIGNAL);
    return 0;
}
int server_puts_query(MYSQL *mysql, int args_len, char *args, int netfd, Client_info *pclient_info, pthread_mutex_t *mutex, int now_path_id, int user_id)
{
    char op_args[256];
    sprintf(op_args, "%s %s", "PUTS_QUERY", args);

    ResponsePackage response;
    char argbuf[512]={0};
    memcpy(argbuf,args,args_len);
    char *addr1=strtok(argbuf," ");//客户端文件的地址
    char *addr2=strtok(NULL," ");//服务端要存储的文件的地址
    printf("addr2 = %s\n", addr2);
    char *md5 = strtok(NULL, " ");

    char c_father_info[256] = {0};
    sprintf(c_father_info, "%d %d %d", netfd, user_id, now_path_id);

    char absolutePath[1024] = {0}; 
    if(getTruePath(user_id,now_path_id,addr2,strlen(addr2),mysql,&response,absolutePath,netfd)==-1)
    {
        printf("gertureret 失败！\n");
        return -1;
    }
    char sql[4096]={0};

    char *filename;
    char *fileFatherPath;
    split_path(addr1, &fileFatherPath, &filename);
    printf("addr1 == %s\n", addr1);
    printf("filename = %s\n", filename);

    char path[2048] = {0};
    sprintf(path,"%s/%s",absolutePath,filename);
    //查询path是否存在
    printf("path =========%s\n", path);
    sprintf(sql, "select * from fd_data where path = '%s' and file_dir_type <> %d ;", path,is_Dir);
    int sqlret = mysql_query(mysql,sql);
    if(sqlret != 0)
    {
        printf("server_puts_query 1 sql error\n");
        free(filename);
        free(fileFatherPath);
        return -1;
    }
    MYSQL_RES* psqlRes = mysql_store_result(mysql);
    my_ulonglong resrows = mysql_num_rows(psqlRes);
    MYSQL_ROW row = mysql_fetch_row(psqlRes);

    if(resrows != 0)
    {
        printf("rew[6] = %s\n md5 = %s\n", row[6], md5);
        if (strcmp(row[6], md5) != 0)
        {
            sendError(netfd,"相同目录下已有同名文件！");
            free(filename);
            free(fileFatherPath);
            return -1;
        }
        else
        {
            off_t filesize = 0;
            char savePath[512] = {0};
            sprintf(savePath,"%s/%s",userDir,md5);
            struct stat file_stat;
            if (stat(savePath, &file_stat) == -1) {
                printf("savePath = %s\n", savePath);
                printf("server_puts_query 6 stat error\n");
                return -1;
            }
            filesize = file_stat.st_size;

            filesize = filesize - (filesize % 4096);

            char sendargs[512]={0};
            sprintf(sendargs,"%s %ld %s",args,filesize,c_father_info);
            int sendargs_len = strlen(sendargs);
            int sendtype = RES_PUTS_COMFIRM;
            send(netfd,&sendtype,sizeof(int),MSG_NOSIGNAL);
            send(netfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
            send(netfd,sendargs,strlen(sendargs),MSG_NOSIGNAL);
            free(filename);
            free(fileFatherPath);
            return 0;
        }
    }
    else
    {

        char user_name[256]={0};
        char p_id[256] = {0};

        bzero(sql,sizeof(sql));
        sprintf(sql, "select user_name from user_data where user_id = %d;", user_id);
        sqlret = mysql_query(mysql,sql);
        if(sqlret != 0)
        {
            printf("server_puts_query 2 sql error\n");
            free(filename);
            free(fileFatherPath);
            return -1;
        }
        psqlRes = mysql_store_result(mysql);
        row = mysql_fetch_row(psqlRes);
        memcpy(user_name,row[0],strlen(row[0]));

        bzero(sql,sizeof(sql));
        sprintf(sql, "select id from fd_data where path = '%s';", absolutePath);
        sqlret = mysql_query(mysql,sql);
        if(sqlret != 0)
        {
            printf("server_puts_query 3 sql error\n");
            free(filename);
            free(fileFatherPath);
            return -1;
        }
        psqlRes = mysql_store_result(mysql);
        row = mysql_fetch_row(psqlRes);
        memcpy(p_id,row[0],strlen(row[0]));


        bzero(sql,sizeof(sql));
        sprintf(sql, "insert into fd_data(file_dir_name,user_name,p_id,file_dir_type,path,hash,is_delete) values ('%s','%s',%d,%d,'%s','%s',%d);", filename, user_name, atoi(p_id), is_File, path, md5, 0);
        sqlret = mysql_query(mysql,sql);
        if(sqlret != 0)
        {
            printf("server_puts_query 4 sql error\n");
            free(filename);
            free(fileFatherPath);
            return -1;
        }

        char savePath[512] = {0};
        sprintf(savePath,"%s/%s",userDir,md5);

        off_t filesize = 0;
        if(access(savePath,F_OK) == -1)
        {
            printf("savepath ++++= %s\n", savePath);
            int savefd = open(savePath, O_CREAT, 0666);
            if(savefd == -1)
            {
                printf("open失败！\n");
                free(filename);
                free(fileFatherPath);
                return -1;
            }
            close(savefd);
            char sendargs[512]={0};
            filesize = 0;
            sprintf(sendargs,"%s %ld %s",args,filesize,c_father_info);
            int sendargs_len = strlen(sendargs);
            int sendtype = RES_PUTS_COMFIRM;
            send(netfd,&sendtype,sizeof(int),MSG_NOSIGNAL);
            send(netfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
            send(netfd,sendargs,strlen(sendargs),MSG_NOSIGNAL);
        }
        else
        {
            sprintf(savePath,"%s/%s",userDir,md5);
            struct stat file_stat;
            if (stat(savePath, &file_stat) == -1) {
                printf("open_pathhhhhhh = %s\n", savePath);
                printf("server_puts_query 7 stat error\n");
                free(filename);
                free(fileFatherPath);
                return -1;
            }
            filesize = file_stat.st_size;

            filesize = filesize - (filesize % 4096);

            char sendargs[512]={0};
            sprintf(sendargs,"%s %ld %s",args,filesize,c_father_info);
            int sendargs_len = strlen(sendargs);
            int sendtype = RES_PUTS_COMFIRM;
            send(netfd,&sendtype,sizeof(int),MSG_NOSIGNAL);
            send(netfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
            send(netfd,sendargs,strlen(sendargs),MSG_NOSIGNAL);
        }
        /* bzero(sql,sizeof(sql)); */
        /* sprintf(sql,"select * from fd_data where hash = '%s'",md5); */
        /* sqlret = mysql_query(mysql,sql); */
        /* if(sqlret != 0) */
        /* { */
        /*     printf("server_puts_query 5 sql error\n"); */
        /*     return -1; */
        /* } */
        /* psqlRes = mysql_store_result(mysql); */
        /* resrows = mysql_num_rows(psqlRes); */

        free(filename);
        free(fileFatherPath);
        return 0;
    }

}

int server_puts_begin(MYSQL *mysql,int *epfd, int args_len, char *args, int netfd, Client_info *pclient_info, pthread_mutex_t *mutex, int now_path_id, int user_id)
{
    char op_args[256];
    sprintf(op_args, "%s %s", "PUTS_BEGIN", args);

    // epollDel(*epfd,netfd);
    char argbuf[1024]={0};
    memcpy(argbuf,args,args_len);
    char *addr1=strtok(argbuf," ");//客户端文件的地址
    char *addr2=strtok(NULL," ");//服务端要存储的文件的地址
    char *md5=strtok(NULL," ");
    char *offsetbuf=strtok(NULL," ");
    char *a = strtok(NULL," ");
    char *b = strtok(NULL," ");
    char *c= strtok(NULL," ");
    char *filesizebuf=strtok(NULL," ");
    printf("filesizebuf ===== %s\n", filesizebuf);
    off_t offset = 0;
    sscanf(offsetbuf,"%ld",&offset);

    // printf("offsetbuf = %s\n", offsetbuf);
    // printf("filesizebuf = %s\n", filesizebuf);

    off_t filesize = 0;
    sscanf(filesizebuf,"%ld",&filesize);

    char open_path[512] = {0};

    sprintf(open_path,"%s/%s",userDir,md5);
    int open_fd = open(open_path,O_RDWR);
    lseek(open_fd,offset,SEEK_SET);

    long processed = offset;
    char recvbuf[4096]={0};

    struct stat file_stat;
    if (stat(open_path, &file_stat) == -1) {
        printf("open_pathhhhhhh = %s\n", open_path);
        printf("server_puts_query  6 stat error\n");
        return -1;
    }
    printf("filesize = %ld\n", filesize);

    while(processed<filesize)
    {
        bzero(recvbuf,4096);
        int recvsize = recv(netfd,recvbuf,4096,0);
        if(recvsize == 0)
        {
            break;
        }
        write(open_fd,recvbuf,recvsize);
        processed+=recvsize;
    }

    close(open_fd); // 关闭文件描述符
    printf("%d puts end\n",netfd);
    
    close(netfd);

    return 0;
}
int server_gets_query(MYSQL *mysql, int args_len, char *args, int netfd, Client_info *pclient_info, pthread_mutex_t *mutex, int now_path_id, int user_id)
{
    char op_args[256];
    sprintf(op_args, "%s %s", "GETS_QUERY", args);

    ResponsePackage response;
    char argbuf[512]={0};
    memcpy(argbuf,args,args_len);
    char *addr1=strtok(argbuf," ");//服务端文件地址
    char *addr2=strtok(NULL," ");//客户想要存储到本地的地址

    char c_father_info[64] = {0};
    sprintf(c_father_info,"%d %d %d", netfd, user_id, now_path_id);

    char absolutePath[1024] = {0};
    if(getTruePath(user_id,now_path_id,addr1,strlen(addr1),mysql,&response,absolutePath,netfd)==-1)
    {
        return -1;
    }
    char sql[2048]={0};
    sprintf(sql,"select hash from fd_data where path = '%s'",absolutePath);
    int sqlret = mysql_query(mysql,sql);
    if(sqlret != 0)
    {
        printf("server_gets_query 1 sql error\n");
        return -1;
    }
    MYSQL_RES* psqlRes = mysql_store_result(mysql);
    my_ulonglong resrows = mysql_num_rows(psqlRes);
    if(resrows == 0)
    {
        sendError(netfd,"请求的文件不存在");
        return -1;
    }

    MYSQL_ROW row = mysql_fetch_row(psqlRes);
    char filePath[512]={0};
    sprintf(filePath,"%s/%s",userDir,row[0]);
    printf("fileParh:%s",filePath);

    struct stat file_stat;
    if (stat(filePath, &file_stat) == -1) {
        printf("server_gets_query open filePath = %s\n", filePath);
        printf("server_puts_query 5 stat error\n");
        return -1;
    }
    off_t filesize = file_stat.st_size;

    int type = RES_GETS_COMFIRM;
    // char sendargs[1024]={0};
    // sprintf(sendargs,"%s %ld %s %s",args,filesize,row[0],c_father_info);
    // int sendargs_len = strlen(sendargs);
    // send(netfd,&type,sizeof(int),MSG_NOSIGNAL);
    // send(netfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
    // send(netfd,sendargs,sendargs_len,MSG_NOSIGNAL);

    char sendargs[1024]={0};
    int dataServerNum = sizeof(dataServerArr)/sizeof(dataServerArr[0]);
    char dataServerStr[512]={0};
    for(int i = 0;i<dataServerNum;++i)
    {
        sprintf(dataServerStr,"%s %s",dataServerStr,dataServerArr[i]);
    }
    sprintf(sendargs,"%s %ld %s %s %d %s",args,filesize,row[0],c_father_info,dataServerNum,dataServerStr);
    int sendargs_len = strlen(sendargs);
    send(netfd,&type,sizeof(int),MSG_NOSIGNAL);
    send(netfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
    send(netfd,sendargs,sendargs_len,MSG_NOSIGNAL);

    return 0;
}
int server_gets_begin(MYSQL *mysql, int *epfd, int args_len, char *args, int netfd, Client_info *pclient_info, pthread_mutex_t *mutex, int now_path_id, int user_id)
{
    char op_args[256];
    sprintf(op_args, "%s %s", "GETS_BEGIN", args);

    char argbuf[512]={0};
    memcpy(argbuf,args,args_len);
    char *addr1 = strtok(argbuf," ");//客户端文件的地址
    char *addr2 = strtok(NULL," ");//服务端要存储的文件的地址
    char *offsetbuf = strtok(NULL," ");
    char *md5=strtok(NULL," "); 

    // char *a = strtok(NULL, " ");
    // char *b = strtok(NULL, " ");
    // char *c = strtok(NULL, " ");

    char *sendsizebuf = strtok(NULL, " ");


    off_t offset = 0;
    sscanf(offsetbuf,"%ld",&offset);

    off_t filesize = 0;
    sscanf(sendsizebuf,"%ld",&filesize);

    printf("offset=%ld size=%ld\n",offset,filesize);

    char localFilePath[512] = {0};
    sprintf(localFilePath,"%s/%s",userDir,md5);
    int open_fd = open(localFilePath,O_RDWR);
    lseek(open_fd,offset,SEEK_SET);
    
    // struct stat file_stat;
    // if (stat(localFilePath, &file_stat) == -1) {

    //     return -1;
    // }

    // 文件大小
    
    long processed = offset;
    filesize = filesize+processed;
    printf("DS3 %ld-%ld\n",processed,filesize);
    //long max_size = (long)2*1024*1024*1024;
    long max_size = (long)512*1024*1024;//512M
    while(processed<filesize)
    {
        long sendsize = filesize - processed > (max_size)?max_size:filesize - processed;
        char* p = (char*)mmap(NULL,sendsize,PROT_READ|PROT_WRITE,MAP_SHARED,open_fd,processed);
        send(netfd,(void*)p,sendsize,MSG_NOSIGNAL);
        munmap(p,sendsize);
        processed+=sendsize;
        printf("%ld/%ld\n",processed,filesize);
    }

    // char readbuf[4096]={0};
    // while(processed<filesize)
    // {
    //     bzero(readbuf,4096);
    //     int recvsize = pread(open_fd,readbuf,4096,processed);
    //     send(netfd,readbuf,recvsize,MSG_NOSIGNAL);
    //     processed+=recvsize;
    //     printf("%ld/%ld\n",processed,filesize);
    // }

    //释放资源
    close(open_fd); // 关闭文件描述符
    printf("client %d gets end\n",netfd);
    close(netfd);
    return 0;
}
